package com.xinqi.modules.exam.common.assistant;

import com.alibaba.fastjson2.JSON;
import com.xinqi.common.base.enums.YesNoEnum;
import com.xinqi.common.base.enums.YesNoNumberEnum;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.R;
import com.xinqi.common.base.utils.number.BigDecimals;
import com.xinqi.common.core.constant.Constants;
import com.xinqi.common.core.enums.AssistantMessageTypeEnum;
import com.xinqi.common.core.enums.AssistantStateEnum;
import com.xinqi.common.core.enums.CourseContentTypeEnum;
import com.xinqi.common.core.enums.SysMessageEnum;
import com.xinqi.modules.chat.chat.official.client.ChatAssistantContentClient;
import com.xinqi.modules.chat.chat.official.dto.req.ChatAssistantContentCreateDTO;
import com.xinqi.modules.chat.chat.official.json.BaseMessage;
import com.xinqi.modules.chat.chat.official.json.EvaluationMessage;
import com.xinqi.modules.chat.chat.rongyun.RemoteRongyunClient;
import com.xinqi.modules.chat.chat.template.TemplateMessageDTO;
import com.xinqi.modules.exam.common.assistant.enums.MessageSubTypeEnum;
import com.xinqi.modules.exam.common.constants.ExamI18nConstants;
import com.xinqi.modules.exam.common.convert.AssistantConvert;
import com.xinqi.modules.exam.common.error.ExamErrors;
import com.xinqi.modules.exam.common.manager.CommonClassManager;
import com.xinqi.modules.exam.common.mapper.dto.ClassBaseDTO;
import com.xinqi.modules.exam.common.mapper.dto.ClassStudentBaseDTO;
import com.xinqi.modules.exam.paper.domain.CourseExamPaperConfigEntity;
import com.xinqi.modules.exam.paper.domain.CourseExamPaperEntity;
import com.xinqi.modules.exam.paper.manager.CourseExamPaperConfigManager;
import com.xinqi.modules.exam.paper.manager.CourseExamPaperManager;
import com.xinqi.modules.exam.student.dto.req.CourseExamPaperStudentQueryDTO;
import com.xinqi.modules.exam.student.dto.rsp.CourseExamPaperStudentResultDTO;
import com.xinqi.modules.exam.student.manager.CourseExamPaperStudentManager;
import com.xinqi.modules.user.user.client.UserClient;
import com.xinqi.modules.user.user.dto.rsp.UserBaseInfoDO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 新奇助手测评消息
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ChatAssistantExamService {
    private final UserClient userClient;
    private final AssistantConvert assistantConvert;
    private final RemoteRongyunClient remoteRongyunClient;
    private final CommonClassManager commonClassManager;
    private final CourseExamPaperManager courseExamPaperManager;
    private final ChatAssistantContentClient chatAssistantContentClient;
    private final CourseExamPaperStudentManager courseExamPaperStudentManager;
    private final CourseExamPaperConfigManager courseExamPaperConfigManager;

    /**
     * 发送消息(融云)k
     */
    public void sendRYunMessage(Long examId, List<Long> students, MessageSubTypeEnum messageEnum) {
        CourseExamPaperEntity examPaper = Optional.ofNullable(courseExamPaperManager.findBaseById(examId))
            .orElseThrow(() -> ExamErrors.EXAM_NOT_EXIST.asException(ExamI18nConstants.测评不存在));
        sendRYunMessage(examPaper, students, messageEnum);
    }

    public void sendRYunMessage(CourseExamPaperEntity examPaper, List<Long> students, MessageSubTypeEnum messageEnum) {
        if (examPaper == null) {
            throw ExamErrors.EXAM_NOT_EXIST.asException(ExamI18nConstants.测评不存在);
        }
        ClassBaseDTO classBase = Optional.ofNullable(commonClassManager.findBaseByClassId(examPaper.getClassId()))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException("班级不存在"));
        UserBaseInfoDO user = R.as(userClient.getUserBaseInfo(examPaper.getUserId()));
        String[] targetIds = students.stream().map(String::valueOf).toArray(String[]::new);
        TemplateMessageDTO bean = new TemplateMessageDTO();
        bean.setType(messageEnum.getCode());
        bean.setClassId(examPaper.getClassId().toString());
        bean.setFromUserId("0"); // 0代表系统用户
        bean.setToUserId(examPaper.getClassId().toString());
        Map<String, Object> content = new HashMap<>();
        content.put("type", CourseContentTypeEnum.EXAM.getCode());
        content.put("avatar", user.getAvatar());
        content.put("name", user.getNickname());
        content.put("contentId", examPaper.getId());
        content.put("title", examPaper.getName());
        content.put("courseId", classBase.getCourseId());
        String msg = "";
        if (messageEnum == MessageSubTypeEnum.催交) {
            // 催交41
            bean.setType(SysMessageEnum.EXAM_CALL.getCode());
            msg = user.getNickname() + "发布的测评【" + examPaper.getName() + "】，需要你尽快提交";
        } else if (messageEnum == MessageSubTypeEnum.强制交卷) {
            // 强制交卷42
            bean.setType(SysMessageEnum.EXAM_HAND_STOP.getCode());
            msg = user.getNickname() + "发布的测评【" + examPaper.getName() + "】，已强制收卷";
        } else if (messageEnum == MessageSubTypeEnum.测评已被删除) {
            // 测评已被删除44
            bean.setType(SysMessageEnum.EXAM_DELETED.getCode());
            msg = user.getNickname() + "发布的测评【" + examPaper.getName() + "】，已被删除";
        }
        content.put("content", msg);
        content.put("end_time", examPaper.getEndTime());
        bean.setContent(JSON.toJSONString(content));
        String body = JSON.toJSONString(bean);
        remoteRongyunClient.creatSysUserSend(targetIds, body);
        log.info("发送融云消息，messageSubtype = {}, examId = {}, userIds = {}, msg = {}", messageEnum.getDescription(), examPaper.getId(), targetIds, body);
    }

    /**
     * 发送消息
     */
    public void sendMessage(Long examId, List<Long> students, MessageSubTypeEnum opType) {
        List<ChatAssistantContentCreateDTO> list = getMessageContent(examId, students, opType);
        if (CollectionUtils.isNotEmpty(list)) {
            chatAssistantContentClient.batchInsert(list);
            String body = JSON.toJSONString(list);
            log.info("发送助手消息，messageSubtype = {}, examId = {},  userIds = {}, msg = {}", opType.getDescription(), examId, students, body);
        }
    }

    /**
     * 新奇助手测评催交、打回、成绩
     *
     * @param examId   作业成绩
     * @param students 学生id列表
     * @param opType   消息子类型， 0-发布；1-催交；2-打回；3-成绩；4-提醒；5-开始；
     */
    public List<ChatAssistantContentCreateDTO> getMessageContent(Long examId, List<Long> students, MessageSubTypeEnum opType) {
        CourseExamPaperEntity examPaper = Optional.ofNullable(courseExamPaperManager.findBaseById(examId))
            .orElseThrow(() -> ExamErrors.EXAM_NOT_EXIST.asException(ExamI18nConstants.测评不存在));
        CourseExamPaperConfigEntity config = Optional.ofNullable(courseExamPaperConfigManager.findByExamId(examId))
            .orElseThrow(() -> CommonErrors.BAD_REQUEST.asException("测评配置不存在"));

        ChatAssistantContentCreateDTO initCreate = initChatAssistantContent(AssistantMessageTypeEnum.EXAM);
        EvaluationMessage initMessage = this.initEvaluationMessage(examPaper, config);

        // 如果是发送成绩，需要查询学生的成绩
        Map<Long, CourseExamPaperStudentResultDTO> studentMap = null;
        if (Objects.equals(MessageSubTypeEnum.成绩, opType)) {
            CourseExamPaperStudentQueryDTO queryDTO = new CourseExamPaperStudentQueryDTO();
            queryDTO.setExamId(examId);
            queryDTO.setStudentIds(students);
            studentMap = courseExamPaperStudentManager.findList(queryDTO)
                .stream().collect(Collectors.toMap(CourseExamPaperStudentResultDTO::getStudentId, v -> v));
        }
        List<ClassStudentBaseDTO> studentList = commonClassManager.findStudentBase(examPaper.getClassId(), students);
        List<ChatAssistantContentCreateDTO> list = new ArrayList<>();
        for (ClassStudentBaseDTO item : studentList) {
            ChatAssistantContentCreateDTO create = assistantConvert.create(initCreate);
            create.setType(opType.getCode());
            create.setContentId(examId);
            create.setRecipient(item.getStudentId());
            // 消息体
            EvaluationMessage message = assistantConvert.create(initMessage);
            message.setClassRole(item.getClassRole());
            // 如果是成绩需要设置成绩
            if (Objects.equals(MessageSubTypeEnum.成绩, opType) && studentMap != null) {
                Optional.ofNullable(studentMap.get(item.getStudentId()))
                    .ifPresent(v -> message.setStudentScore(BigDecimals.toString(v.getScore())));
            }
            create.setMessageContext(JSON.toJSONString(message));
            list.add(create);
        }
        return list;
    }

    /**
     * 初始化发布基本消息体
     */
    private ChatAssistantContentCreateDTO initChatAssistantContent(AssistantMessageTypeEnum type) {
        // 初始化基本信息
        ChatAssistantContentCreateDTO assistant = new ChatAssistantContentCreateDTO();
        assistant.setType(MessageSubTypeEnum.发布.getCode());
        assistant.setMessageType(type.getType());
        assistant.setProgressState(AssistantStateEnum.PROGRESS.getCode());
        return assistant;
    }

    /**
     * 初始化消息内容公共方法
     */
    private EvaluationMessage initEvaluationMessage(CourseExamPaperEntity entity, CourseExamPaperConfigEntity config) {
        BaseMessage base = initBaseMessage(entity.getClassId());
        EvaluationMessage message = JSON.parseObject(JSON.toJSONString(base), EvaluationMessage.class);
        message.setTitle(entity.getName());
        message.setClassId(entity.getClassId());
        message.setContentId(entity.getId());
        if (Objects.equals(YesNoNumberEnum.NO.getCode(), config.getIsLimitAnswerTime())) {
            message.setTimeLimit("不限时");
            message.setIsTimeLimit(Integer.parseInt(YesNoEnum.NO.getCode()));
        } else {
            message.setTimeLimit(config.getAnswerDuration() + "分钟");
            message.setIsTimeLimit(Integer.parseInt(YesNoEnum.YES.getCode()));
        }
        message.setParticipateNum(0);
        message.setNotParticipateNum(0);
        message.setScoreSetup(Integer.parseInt(config.getIsPublishScore().getCode()));
        message.setStartTime(entity.getStartTime());
        message.setEndTime(entity.getEndTime());
        return message;
    }

    /**
     * 初始化发布基本消息内容
     */
    private BaseMessage initBaseMessage(Long classId) {
        // 获取班级信息
        ClassBaseDTO classResult = commonClassManager.findBaseByClassId(classId);
        BaseMessage message = new BaseMessage();
        if (Objects.nonNull(classResult)) {
            message.setCourseName(classResult.getCourseName() + Constants.SPACE_DROP + classResult.getClassName());
            message.setClassId(classId);
        } else {
            message.setCourseName(Constants.SPACE_DROP);
            message.setClassId(classId);
        }
        return message;
    }
}
